package org.project.d.starter.network;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.NetUtil;
import org.project.d.network.Connection;
import org.project.d.network.coder.TcpCombinedChannelDuplexHandler;
import org.project.d.network.handler.ConnectionEvent;
import org.project.d.network.handler.ConnectionHandler;
import org.project.d.network.handler.HeartEvent;
import org.project.d.network.handler.MsgDispatcherHandler;
import org.project.d.network.online.*;
import org.project.d.network.start.ChannelHandlerInit;
import org.project.d.starter.network.properties.TcpConfig;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetSocketAddress;

/**
 * @author lin
 * @version V1.0
 * @description
 * @date 2020/10/19 5:23 下午
 */
@Configuration
public class UserRedisManagerConfig {
    private UserStateManager userStateManager;
    protected ChannelHandlerInit channelHandlerInit = new ChannelHandlerInit() {
        private final ChannelHandler connectionHand=new ConnectionHandler(ConnectionEvent.builder().heartEvent(new HeartEvent() {
            @Override
            public void readerIdle(IdleStateEvent idleStateEvent, Connection connection) {

            }

            @Override
            public void writerIdle(IdleStateEvent idleStateEvent, Connection connection) {

            }

            @Override
            public void allIdle(IdleStateEvent idleStateEvent, Connection connection) {
//                connection.close();
                String ip = NetUtil.toSocketAddressString((InetSocketAddress) connection.getChannel().remoteAddress());
                OnlineInfoImpl onlineInfo = new OnlineInfoImpl();
                onlineInfo.setClineAddress(ip);
                userStateManager.offline(onlineInfo);
            }
        }).build());
        private final ChannelHandler msgDispatcherHandler=new MsgDispatcherHandler();

        @Override
        public void channelInit(ChannelPipeline pipeline) {
            pipeline.addLast(new IdleStateHandler(0, 0, 60));
            pipeline.addLast(new TcpCombinedChannelDuplexHandler());
            pipeline.addLast(connectionHand);
            pipeline.addLast(msgDispatcherHandler);
        }
    };
    @Bean
    public TcpConfig tcpConfig(){
        TcpConfig tcpConfig = new TcpConfig();
        tcpConfig.setChannelHandlerInit(channelHandlerInit);
        return tcpConfig;
    }
    @Bean
    public UserStateManager onlineManager(RedissonClient redissonClient){
        OnlineManagerImpl onlineManager = new OnlineManagerImpl(new RedisRemoteOnlineManager(redissonClient), new MapLocalOnlineManager());
        this.userStateManager=onlineManager;
        Runtime.getRuntime().addShutdownHook(new Thread(onlineManager::offlineAll));
        return userStateManager;
    }
}
